home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 January: Mac OS SDK / Dev.CD Jan 96 SDK / Dev.CD Jan 96 SDK1.toast / Development Kits (Disc 1) / AppleScript / Development Tools / Sample Code / 7Edit / C Sources / SVEditFile.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-25  |  15.3 KB  |  668 lines  |  [TEXT/MPS ]

  1. /*
  2.     SVEditFile.c
  3.     
  4.     Version 3.0d9
  5.     
  6.     Copyright © SRL Data 1992, 1993
  7.     
  8.     All rights reserved
  9.     
  10.     Produced by : SRL Data
  11.     Originally Developed for UK.DTS
  12. */
  13.  
  14. /*
  15.   Changes for 3.0d4:
  16.         3-Jul-92 : NH : Change kAEAskUser to kAEAskU on call to DoClose
  17.         
  18. */
  19.     
  20. #include <Errors.h>
  21. #include <Resources.h>
  22. #include <Desk.h>
  23. #include <PLStringFuncs.h>
  24. #include <AppleEvents.h>
  25. #include <AERegistry.h>
  26. #include <StandardFile.h>
  27. #include "SVEditFile.h"
  28.  
  29. /**-----------------------------------------------------------------------
  30.         Name:             FileError
  31.         Purpose:        Puts up an error alert.
  32.     -----------------------------------------------------------------------**/
  33.  
  34.     
  35. #pragma segment File
  36.  
  37. pascal void FileError(Str255 s, Str255 f)
  38.   {
  39.     short    alertResult;
  40.  
  41.     SetCursor(&qd.arrow);
  42.         ParamText(s, f, (unsigned char *)"", (unsigned char *)"");
  43.     alertResult = Alert(ErrorAlert, nil);
  44.     }
  45.  
  46. /**-----------------------------------------------------------------------
  47.         Name:             DoClose
  48.         Purpose:        Closes a window.
  49.     -----------------------------------------------------------------------**/
  50.  
  51. #pragma segment File
  52.  
  53. pascal OSErr DoClose(WindowPtr aWindow,Boolean canInteract,DescType dialogAnswer)
  54.   {
  55.     DPtr    aDocument;
  56.     short   alertResult;
  57.     Str255  theName;
  58.         OSErr   myErr;
  59.                         
  60.         myErr = noErr;
  61.         
  62.     if (gWCount>0)
  63.       {
  64.         aDocument = DPtrFromWindowPtr(aWindow);
  65.             
  66.                 if (aDocument->dirty)
  67.                     if (canInteract && (dialogAnswer==kAEAsk))
  68.                         {
  69.                             if (aDocument->everSaved == false)
  70.                                 GetWTitle(aWindow, theName); /* Pick it up as a script may have changed it */
  71.                             else
  72.                                 PLstrcpy(theName, aDocument->theFileName);
  73.                                 
  74.                             ParamText((unsigned char *)"\pSave Changes for ", theName, (unsigned char *)"", (unsigned char *)"");
  75.                           SetCursor(&qd.arrow);
  76.                             alertResult = Alert(AdviseAlert, nil);
  77.                             switch (alertResult) {
  78.                               case aaSave    :if (aDocument->everSaved == false)
  79.                                                                     {
  80.                                                                         myErr = GetFileNameToSaveAs(aDocument);
  81.                                                                         if (myErr == noErr)
  82.                                                                             myErr = DoSave(aDocument, aDocument->theFSSpec);
  83.                                                                             
  84.                                                                         if (myErr==noErr)
  85.                                                                             AssocAllSections(aDocument);
  86.                                                                     }
  87.                                                                 else
  88.                                                                     myErr = SaveUsingTemp(aDocument);
  89.                                                                 break;
  90.                                                                 
  91.                                 case aaCancel : return(userCanceledErr);
  92.                                                 break;
  93.                                                                 
  94.                                 case aaDiscard: aDocument->dirty = false;
  95.                             }
  96.                         }
  97.                     else
  98.                         {
  99.                             if (dialogAnswer==kAEYes)
  100.                                 if (aDocument->everSaved == false)
  101.                                     {
  102.                                         if (canInteract)
  103.                                             {
  104.                                               myErr = GetFileNameToSaveAs(aDocument);
  105.                                                 if (myErr==noErr)
  106.                                                     myErr = DoSave(aDocument, aDocument->theFSSpec);
  107.                                                 if (myErr==noErr)
  108.                                                     AssocAllSections(aDocument);
  109.                                             }
  110.                                         else    
  111.                                             return(errAENoUserInteraction);
  112.                                     }
  113.                                 else
  114.                                     myErr = SaveUsingTemp(aDocument);
  115.                             else
  116.                                 myErr = noErr; /* Don't save */
  117.                         }
  118.                 
  119.                 if (myErr==noErr)
  120.                     {
  121.                         if (aDocument->numSections)
  122.                             DeRegisterAllSections(aDocument);
  123.                         CloseMyWindow(aWindow);
  124.                     }
  125.             }
  126.         else
  127.           myErr = errAEIllegalIndex;
  128.             
  129.         return(myErr);
  130.     }
  131.  
  132. #pragma segment File
  133.  
  134. //  DoQuit
  135. //  saveOpt - one of kAEAsk,kAEYes,kAENo
  136. //  if kAEYes or kAEAsk then AEInteactWithUser should have been called
  137. //  before DoQuit. Assumes that it can interact if it needs to.
  138.  
  139. pascal void DoQuit(DescType saveOpt)
  140.   {
  141.     WindowPtr    aWindow;
  142.     WindowPtr    nextWindow;
  143.     WindowPeek   nextWPeek;
  144.     short        theKind;
  145.     OSErr        check;
  146.  
  147.     aWindow = FrontWindow();
  148.      
  149.         while (aWindow)
  150.             {
  151.                 nextWPeek  = ((WindowPeek)aWindow)->nextWindow;
  152.                 nextWindow = &nextWPeek->port;
  153.                 if (Ours(aWindow))
  154.                     {
  155.                         check = DoClose(aWindow, true, saveOpt);
  156.                         if (check!=noErr)
  157.                             return;
  158.                     }
  159.                 else
  160.                     {
  161.                         theKind = ((WindowPeek)aWindow)->windowKind;
  162.                         if (theKind < 0)
  163.                             CloseDeskAcc(theKind);
  164.                     }
  165.                 aWindow = nextWindow;
  166.             }     /*WHILE loop*/
  167.         gQuitting = true;
  168.     }
  169.  
  170. pascal OSErr GetFile(FSSpec *theFSSpec)
  171.   {
  172.     SFTypeList         myTypes;
  173.     StandardFileReply  reply;
  174.  
  175.         myTypes[0] = 'TEXT';
  176.  
  177.         StandardGetFile(nil, 1, myTypes, &reply);
  178.  
  179.         if (reply.sfGood)
  180.             {
  181.                 *theFSSpec = reply.sfFile;
  182.                 return(noErr);
  183.             }
  184.         else
  185.             return(userCanceledErr);
  186.  }
  187.  
  188. #pragma segment File
  189.  
  190.  
  191. pascal OSErr DoCreate(FSSpec theSpec)
  192.   {
  193.       OSErr err;
  194.  
  195.       err = FSpCreate(&theSpec, SVEditAppSig, 'TEXT', smSystemScript);
  196.  
  197.       if (err != noErr)
  198.               ShowError((unsigned char *)"\pDoCreate", err);
  199.                 
  200.             return(err);
  201.     }
  202.  
  203. #pragma segment File
  204.  
  205.  
  206. pascal OSErr WriteFile(DPtr      theDocument,
  207.                                              short     refNum,
  208.                        FSSpec    theFSSpec)
  209.   {
  210.     short        resFile;
  211.     long         length;
  212.     HHandle      theHHandle;
  213.     StScrpHandle theSHandle;
  214.     OSErr        err;
  215.     StringHandle theAppName;
  216.         short        oldSelStart;
  217.         short        oldSelEnd;
  218.         Handle       thePHandle;
  219.         Handle       myText;
  220.                 
  221. /*        WriteFile := 1; */
  222.  
  223.     /*first write out the text to the data fork*/
  224.         
  225.         length = (*(theDocument->theText))->teLength;
  226.         
  227.         myText = (*(theDocument->theText))->hText;
  228.         
  229.     HLock(myText);
  230.     
  231.         err = FSWrite(refNum, &length, *myText);
  232.         if (err)
  233.           return(err);
  234.             
  235.     HUnlock(myText);
  236.  
  237.         /*we are writing to a temporary file, so we need to create the resource file*/
  238.         /*before writing out the resources*/
  239.         /*now open the resource file*/
  240.         
  241.         HCreateResFile(theFSSpec.vRefNum, theFSSpec.parID, theFSSpec.name);
  242.         err = ResError();
  243.         if (err)
  244.           {
  245.                 ShowError((unsigned char *)"\pHCreateResFile", err);
  246.                 return(err);
  247.             }
  248.  
  249.     resFile = HOpenResFile(theFSSpec.vRefNum, theFSSpec.parID, theFSSpec.name, fsWrPerm);
  250.     err = ResError();
  251.  
  252.     if (err)
  253.           {
  254.                 ShowError((unsigned char *)"\pHOpenResFile", err);
  255.                 return(err);
  256.             }
  257.  
  258.      /*write out our 'TFSF' resource to file*/
  259.                 
  260.         oldSelStart = (*(theDocument->theText))->selStart;
  261.         oldSelEnd   = (*(theDocument->theText))->selEnd;
  262.         TESetSelect(0,32000, theDocument->theText);
  263.                 
  264.     theSHandle = GetStylScrap(theDocument->theText);
  265.                 
  266.         TESetSelect(oldSelStart,oldSelEnd, theDocument->theText);
  267.                 
  268.     AddResource((Handle)theSHandle, 'TFSF', 255, (unsigned char *)"\pStyle Info");
  269.     err = ResError();
  270.     if (err)
  271.           {
  272.                 ShowError((unsigned char *)"\pAddResource- TFSF", err);
  273.                 return(err);
  274.             }
  275.                     
  276.         /* write out the printer info */
  277.                 
  278.         if (theDocument->thePrintSetup)
  279.             {
  280.                 thePHandle = (Handle)theDocument->thePrintSetup;
  281.                 err = HandToHand(&thePHandle);
  282.                 
  283.                 AddResource(thePHandle, 'TFSP', 255, (unsigned char *)"\pPrinter Info");
  284.                 err = ResError();
  285.                 if (err)
  286.                     {
  287.                         ShowError((unsigned char *)"\pAddResource- TFSP", err);
  288.                         return(err);
  289.                     }
  290.             }
  291.                 
  292.                 
  293.         theHHandle = (HHandle)NewHandle(sizeof(HeaderRec));
  294.     HLock((Handle)theHHandle);
  295.  
  296.         GetFontName(theDocument->theFont, (unsigned char *)&(*theHHandle)->theFont);
  297.         (*theHHandle)->theSize     = theDocument->theSize;
  298.         (*theHHandle)->theStyle    = theDocument->theStyle;
  299.         (*theHHandle)->lastID      = theDocument->lastID;
  300.         (*theHHandle)->numSections = theDocument->numSections;
  301.  
  302.         HUnlock((Handle)theHHandle);
  303.  
  304.         AddResource((Handle)theHHandle, 'TFSS', 255, (unsigned char *)"\pHeader Info");
  305.  
  306.         err = ResError();
  307.         if (err)
  308.             {
  309.                 ShowError((unsigned char *)"\pAddResource- TFSS", err);
  310.                 return(err);
  311.             }
  312.  
  313.         /*if we have any sections, write out the records and resources*/
  314.         
  315.         if (theDocument->numSections)
  316.             {
  317.                 /*now write out the section records*/
  318.                 SaveSections(theDocument);
  319.                 
  320.                 /*write the latest versions of all editions to their containers*/
  321.  
  322.                 WriteAllEditions(theDocument);
  323.                 /*now close the resource file*/
  324.                 err = ResError();
  325.                 if (err)
  326.                     {
  327.                         ShowError((unsigned char *)"\pCloseResFile", err);
  328.                         return(err);
  329.                     }
  330.             }
  331.  
  332.         /*Now put an AppName in for Finder in 7.0*/
  333.  
  334.         theAppName = (StringHandle)NewHandle(6);
  335.         PLstrcpy(*theAppName,(unsigned char *)"\p7Edit");
  336.         
  337.         AddResource((Handle)theAppName, 'STR ', - 16396, (unsigned char *)"\pFinder App Info");
  338.  
  339.         err = ResError();
  340.  
  341.         if (err)
  342.             {
  343.                 ShowError((unsigned char *)"\pAppName", err);
  344.                 return(err);
  345.             }
  346.  
  347.         CloseResFile(resFile);
  348.  
  349.         return(noErr);
  350.     } /* WriteFile */
  351.  
  352. #pragma segment File
  353.  
  354. pascal OSErr ReadFile(DPtr   theDocument,
  355.                                             short  refNum,
  356.                       Str255 fn)
  357.  {
  358.         long            theSize;
  359.         short           resFile;
  360.         OSErr           err;
  361.         HHandle         aHandle;
  362.         Handle          gHandle;
  363.  
  364.         err = GetEOF(refNum, &theSize);
  365.                 if (err)
  366.           return(err);
  367.  
  368.         /*we're only using TE, so check that there is not more than 32K worth of text*/
  369.                 
  370.         if (theSize > 32000)
  371.           return(1);
  372.  
  373.         gHandle = NewHandle(theSize);
  374.         HLock(gHandle);
  375.                 err = FSRead(refNum, &theSize, *gHandle);
  376.                 
  377.         if (err)
  378.           {
  379.             HUnlock(gHandle);
  380.                         return(err);
  381.           }
  382.                                 
  383.                 resFile = HOpenResFile(theDocument->theFSSpec.vRefNum, 
  384.                                                              theDocument->theFSSpec.parID,
  385.                                                              fn,
  386.                                                              fsWrPerm);
  387.                 if (resFile == -1)
  388.                     err = fnfErr;
  389.                     
  390.                 theDocument->numSections = 0;
  391.                 
  392.                 if (err==noErr)
  393.                     {
  394.                         aHandle = nil;
  395.         
  396.                         if (Count1Resources('TFSS'))
  397.                             aHandle = (HHandle)Get1Resource('TFSS', 255);
  398.         
  399.                         if (aHandle)
  400.                             theDocument->numSections = (*aHandle)->numSections;
  401.                             
  402.                         /*
  403.                             New Format Info
  404.                         */
  405.                         
  406.                         aHandle = nil;
  407.                         
  408.                         if (Count1Resources('TFSF'))
  409.                             aHandle = (HHandle)Get1Resource('TFSF', 255);
  410.                             
  411.                         HLock(gHandle);
  412.                         TEStylInsert(    *gHandle,
  413.                                                     GetHandleSize(gHandle),
  414.                                                     (StScrpHandle)aHandle,
  415.                                                     theDocument->theText);
  416.                                         
  417.                         HUnlock(gHandle);
  418.                         
  419.                         /*
  420.                             If there is a print record saved, ditch the old one
  421.                             created by new document and fill this one in
  422.                         */
  423.                         if (Count1Resources('TFSP'))
  424.                             {
  425.                                 if (theDocument->thePrintSetup)
  426.                                     DisposHandle((Handle)theDocument->thePrintSetup);
  427.                                 
  428.                                 theDocument->thePrintSetup = (THPrint)Get1Resource('TFSP', 255);
  429.                               err = HandToHand((Handle *)&theDocument->thePrintSetup);
  430.                                 
  431.                                 PrValidate(theDocument->thePrintSetup);
  432.                             }
  433.                                                     
  434.                         if (theDocument->numSections)
  435.                             {
  436.                                 ReadSectionRecords(theDocument);
  437.                                 ReadAllSectionResources(theDocument);
  438.                             }
  439.         
  440.                         CloseResFile(resFile);
  441.         
  442.                         err = ResError();
  443.                         if (err)
  444.                             {
  445.                                 ShowError((unsigned char *)"\pread file- CloseResFile", err);
  446.                                 return(err);
  447.                             }
  448.           }
  449.                 else
  450.                     TESetText(*gHandle, 
  451.                               GetHandleSize(gHandle), 
  452.                                         theDocument->theText);
  453.                     
  454.                 if (gHandle)
  455.                     DisposHandle(gHandle);
  456.                     
  457.                 if (err==fnfErr)
  458.                     err = noErr;
  459.  
  460.         return(err);
  461.         } /* ReadFile */
  462.  
  463. /** -----------------------------------------------------------------------
  464.         Name:             GetFileContents
  465.         Purpose:        Opens the document specified by theFSSpec and puts
  466.                                 the contents into theDocument.
  467.      -----------------------------------------------------------------------**/
  468.  
  469.     
  470. #pragma segment File
  471.  
  472. pascal OSErr GetFileContents(FSSpec theFSSpec, DPtr theDocument)
  473.   {
  474.      OSErr            err;
  475.      short            theRefNum;
  476.  
  477.             /*this can be called from two places- on an OpenDoc AppleEvent*/
  478.             /*and by the user just selecting Open from the File Menu*/
  479.             /*assume that the CFS is correct when the routine is called*/
  480.  
  481.             err = FSpOpenDF(&theFSSpec,
  482.                                           fsRdWrPerm,
  483.                                           &theRefNum);
  484.             if (err)
  485.                 {
  486.                     ShowError((unsigned char *)"\pFSpOpenDF", err);
  487.                     return(err);
  488.                 }
  489.             else
  490.                 {
  491.                     err = ReadFile(theDocument, theRefNum, theFSSpec.name);
  492.                     if (err)
  493.                         {
  494.                             ShowError((unsigned char *)"\pReadFile", err);
  495.                             return(err);
  496.                         }
  497.                     err=FSClose(theRefNum);
  498.                     if (err)
  499.                         {
  500.                             ShowError((unsigned char *)"\pFSClose", err);
  501.                             return(err);
  502.                         }
  503.                     return(noErr);
  504.                 }
  505.         }
  506.  
  507.     
  508. #pragma segment File
  509.  
  510. pascal OSErr SaveUsingTemp(DPtr theDocument)
  511.   {
  512.     Str255           tempName;
  513.     OSErr            err;
  514.         FSSpec                tempFSSpec;
  515.  
  516.         /*save the file to disk using a temporary file*/
  517.         /*this is the recommended way of doing things*/
  518.         /*first write out the file to disk using a temporary filename*/
  519.         /*if it is sucessfully written, exchange the temporary file with the last one saved*/
  520.     /*then delete the temporary file- so if anything goes wrong, the original version is still there*/
  521.         /*first generate the temporary filename*/
  522.  
  523.         GetTempFileName(theDocument, tempName);
  524.         /*create this file on disk*/
  525.  
  526.         tempFSSpec      = theDocument->theFSSpec;
  527.         PLstrcpy(tempFSSpec.name,tempName);
  528.             
  529.         err = DoCreate(tempFSSpec);    
  530.  
  531.         /*now save the file as normal*/
  532.         
  533.         if (err==noErr)
  534.             err = DoSave(theDocument, tempFSSpec);
  535.         
  536.         if (err == noErr)
  537.             err = FSpExchangeFiles(&tempFSSpec, &theDocument->theFSSpec);
  538.  
  539.         /*we've exchanged the files, now delete the temporary one*/
  540.         
  541.         if (err==noErr)
  542.           err = FSpDelete(&tempFSSpec);
  543.  
  544.         return(err);
  545.     }
  546.  
  547.     
  548. #pragma segment File
  549.  
  550. /*
  551.     Fills in the document record with the user chosen destination
  552. */
  553.  
  554. pascal OSErr GetFileNameToSaveAs(DPtr theDocument)
  555.     {            
  556.     StandardFileReply   reply;
  557.     OSErr               err;
  558.         Str255              suggestName;
  559.  
  560.         GetWTitle(theDocument->theWindow, suggestName);
  561.  
  562.         StandardPutFile((unsigned char *)"\pSave Document As:", suggestName, &reply);
  563.  
  564.     if (reply.sfGood)
  565.             {                
  566.                 err = FSpDelete(&reply.sfFile);
  567.                 
  568.                 if (!((err==noErr) || (err==fnfErr)))
  569.                     return(err);
  570.                 else
  571.                     err = noErr;
  572.                     
  573.                 theDocument->theFSSpec = reply.sfFile;
  574.                 PLstrcpy(theDocument->theFileName, reply.sfFile.name);
  575.             }
  576.         else
  577.             err = userCanceledErr;
  578.         
  579.         return(err);
  580.  } /* GetFileNameToSaveAs */
  581.  
  582.     
  583. #pragma segment File
  584.  
  585. pascal OSErr DoSave(DPtr   theDocument, FSSpec theFSSpec)
  586.   {
  587.     short      refNum;
  588.     OSErr      fileErr;
  589.  
  590.         fileErr = FSpOpenDF(&theFSSpec, fsRdWrPerm, &refNum);
  591.         
  592.         if (fileErr == fnfErr)
  593.             {
  594.               fileErr = DoCreate(theFSSpec);
  595.                 
  596.                 if (fileErr)
  597.                     return(fileErr);
  598.                     
  599.                 fileErr = FSpOpenDF(&theFSSpec, fsRdWrPerm, &refNum);
  600.             }
  601.  
  602.         if (fileErr == noErr)
  603.             {
  604.               fileErr = WriteFile(theDocument, refNum, theFSSpec);
  605.                 
  606.                 if (fileErr==noErr)
  607.                     theDocument->dirty = false;
  608.                     
  609.                 fileErr = FSClose(refNum);
  610.             }
  611.         else
  612.             FileError((unsigned char *)"\perror opening file ", theFSSpec.name);
  613.         
  614.         return(fileErr);
  615.     }
  616.  
  617.     
  618. #pragma segment File
  619.  
  620. pascal OSErr OpenOld(FSSpec aFSSpec)
  621.     {        
  622.       DPtr  theDocument;
  623.         OSErr fileErr;
  624.  
  625.         theDocument = NewDocument(true);
  626.         
  627.         SetWTitle(theDocument->theWindow, aFSSpec.name);
  628.         
  629.         SetPort(theDocument->theWindow);
  630.         
  631.         theDocument->theFSSpec   = aFSSpec;
  632.         
  633.         PLstrcpy(theDocument->theFileName,aFSSpec.name);
  634.         
  635.         theDocument->dirty       = false;
  636.         theDocument->everSaved   = true;
  637.  
  638.     fileErr = GetFileContents(aFSSpec, theDocument);
  639.         
  640.         if (fileErr == noErr)
  641.             {
  642.                 ResizeWindow(theDocument);
  643.                 ShowWindow(theDocument->theWindow);
  644.             }
  645.         else
  646.             FileError((unsigned char *)"\pError Opening ", aFSSpec.name);
  647.                     
  648.         return(fileErr);
  649.     } /* OpenOld */
  650.  
  651.     
  652. #pragma segment File
  653.  
  654. pascal OSErr OpenUsingAlias(AliasHandle theAliasH)
  655.   {
  656.     OSErr    err;
  657.     FSSpec   aFSSpec;
  658.     Boolean  dummy;
  659.  
  660.         err = ResolveAlias(nil, theAliasH, &aFSSpec, &dummy);
  661.         
  662.         if (err == noErr)
  663.             err = OpenOld(aFSSpec);
  664.                     
  665.         return(err);
  666.     }
  667.  
  668.